<?php
namespace app\admin\controller;

use think\Db;

class Gen extends Base
{
    private $tn;
    private $tn_cn;
    private $tn_hump;
    private $ext_php;
    private $module;
    private $column_data;
    private $module_path;

    private $prefix        = 'admin_';
    private $template_path = ROOT_PATH . 'extend' . DS . 'template' . DS . 'table' . DS;

    public function index()
    {
        if ($this->post) {
            $this->prefix = get_field('admin_module', ['route' => $this->post['module']], 'prefix');
        }
        $tables = array_column(Db::query('SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = "' . config('database.database') . '" AND TABLE_NAME NOT IN ("admin_admin","admin_images","admin_menu","admin_module","admin_role","system_config","system_status") AND TABLE_NAME LIKE "' . $this->prefix . '%"'), 'TABLE_NAME');
        if ($this->post) {
            $this->returnAPI('', 0, ['tables' => $tables]);
        }
        return $this->fetch('', [
            'modules' => db('module')->where('type', 0)->order(['route'])->column('route'),
            'tables'  => $tables,
        ]);
    }

    public function preview()
    {
        // 完整表名
        $this->tn = $this->post['tn'];
        // 模块路径
        $this->module = $this->post['module'];
        // 表前缀
        $this->prefix = get_field('admin_module', ['route' => $this->module], 'prefix');
        // 模块本地路径
        $this->module_path = ROOT_PATH . 'application' . DS . $this->module . DS;
        // 表名注释
        $tn_cn_result = Db::query('SELECT TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = "' . config('database.database') . '" AND TABLE_NAME = "' . $this->tn . '"');
        $this->tn_cn  = $tn_cn_result[0]['TABLE_COMMENT'];
        // 表字段数据
        $this->column_data = Db::query('SELECT COLUMN_NAME,IS_NULLABLE,DATA_TYPE,IF(COLUMN_COMMENT = "",COLUMN_NAME,COLUMN_COMMENT) COLUMN_COMMENT,COLUMN_TYPE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = "' . config('database.database') . '" AND TABLE_NAME = "' . $this->tn . '" AND COLUMN_NAME <> "id"');
        // 去除表名前缀
        $this->tn = str_replace($this->prefix, '', $this->tn);
        // 表名转驼峰
        $this->tn_hump = underline_hump($this->tn);
        // 控制器，模型，验证器文件名称
        $this->ext_php = DS . $this->tn_hump . '.php';
        if (isset($this->post['preview']) && $this->post['preview'] === 'false') {
            $preview = false;
        } else {
            $preview = true;
        }
        $data = [$this->getTplController($preview), $this->getTplModel($preview), $this->getTplIndexJs($preview), $this->getTplValidate($preview), $this->getTplEditHtml($preview), $this->getTplIndexHtml($preview)];
        if ($preview) {
            return $this->fetch('', [
                'data'   => $data,
                'module' => $this->module,
                'tn'     => $this->prefix . $this->tn,
            ]);
        }
        foreach ($data as $v) {
            @mkdir(dirname($v[0]));
            @file_put_contents($v[0], $v[1]);
        }
        $this->returnAPI('操作成功', 0);
    }
    private function getTplController($preview)
    {
        $file = $this->module_path . 'controller' . $this->ext_php;
        if ($preview) {
            $file = str_replace(ROOT_PATH, '', $file);
        }
        $list = '
            foreach ($list as $k => $v) {';
        foreach ($this->column_data as $column) {
            if (in_array($column['COLUMN_NAME'], ['create_time', 'update_time'])) {
                $list .= '
                $list[$k][\'' . $column['COLUMN_NAME'] . '\'] = date(\'Y-m-d H:i:s\', $v[\'' . $column['COLUMN_NAME'] . '\']);';
            } else if ($column['COLUMN_TYPE'] === 'varchar(233)') {
                $list .= '
                $list[$k][\'' . $column['COLUMN_NAME'] . '\'] = \'<img class="upload-image show-image" src="\' . $v[\'' . $column['COLUMN_NAME'] . '\'] . \'"/>\';';
            }
        }
        $list .= '
            }';
        $content = str_replace(['{{$module}}', '{{$tn_hump}}', '{{$tn}}', '{{$list}}'], [$this->module, $this->tn_hump, $this->tn, $list], file_get_contents($this->template_path . 'controller.php.tpl'));
        return [$file, $content];
    }
    private function getTplModel($preview)
    {
        $create_time = '';
        if (deep_in_array('create_time', $this->column_data)) {
            $create_time = '
    protected $insert = [\'create_time\'];

    protected function setCreateTimeAttr()
    {
        return time();
    }';
        }
        $update_time = '';
        if (deep_in_array('update_time', $this->column_data)) {
            $update_time = '
    protected $update = [\'update_time\'];

    protected function setUpdateTimeAttr()
    {
        return time();
    }';
        }
        $file = $this->module_path . 'model' . $this->ext_php;
        if ($preview) {
            $file = str_replace(ROOT_PATH, '', $file);
        }
        $content = str_replace(['{{$module}}', '{{$tn_hump}}', '{{create_time}}', '{{update_time}}'], [$this->module, $this->tn_hump, $create_time, $update_time], file_get_contents($this->template_path . 'model.php.tpl'));
        return [$file, $content];
    }
    private function getTplIndexJs($preview)
    {
        $file = ROOT_PATH . 'public' . DS . 'static' . DS . 'module' . DS . $this->module . DS . $this->tn . DS . 'index.js';
        if ($preview) {
            $file = str_replace(ROOT_PATH, '', $file);
        }
        $columns = '';
        foreach ($this->column_data as $column) {
            $columns .= '{
                field: \'' . $column['COLUMN_NAME'] . '\',
                title: \'' . $column['COLUMN_COMMENT'] . '\',
                unresize: true,
                align: \'center\'
            }, ';
        }
        $content = str_replace(['{{$tn_cn}}', '{{$columns}}', '{{$tn}}', '{{$module}}'], [$this->tn_cn, $columns, $this->tn, $this->module], file_get_contents($this->template_path . 'module.index.js.tpl'));
        return [$file, $content];
    }
    private function getTplValidate($preview)
    {
        $rule    = '';
        $message = '';
        $scene   = '';
        foreach ($this->column_data as $column) {
            if (!in_array($column['COLUMN_NAME'], ['create_time', 'update_time'])) {
                if ($column['IS_NULLABLE'] === 'NO') {
                    $rule .= '
        \'' . $column['COLUMN_NAME'] . '\' => \'require';
                    $message .= '
        \'' . $column['COLUMN_NAME'] . '.require\' => \'' . $column['COLUMN_COMMENT'] . '为必填项\',';
                    if (in_array($column['DATA_TYPE'], ['int', 'decimal', 'float', 'double'])) {
                        $rule .= '|number';
                        $message .= '
        \'' . $column['COLUMN_NAME'] . '.number\' => \'' . $column['COLUMN_COMMENT'] . '需为数字\',';
                    }
                    $rule .= '\',';
                    $scene .= '
            \'' . $column['COLUMN_NAME'] . '\',';
                }
            }
        }
        $file = $this->module_path . 'validate' . $this->ext_php;
        if ($preview) {
            $file = str_replace(ROOT_PATH, '', $file);
        }
        $content = str_replace(['{{$module}}', '{{$tn_hump}}', '{{$rule}}', '{{$message}}', '{{$scene}}'], [$this->module, $this->tn_hump, $rule, $message, $scene], file_get_contents($this->template_path . 'validate.php.tpl'));
        return [$file, $content];
    }
    private function getTplEditHtml($preview)
    {
        $columns = '';
        foreach ($this->column_data as $column) {
            if (!in_array($column['COLUMN_NAME'], ['create_time', 'update_time'])) {
                $columns .= '
    <div class="layui-form-item">
        <label class="layui-form-label">
            ' . $column['COLUMN_COMMENT'] . '
        </label>
        <div class="layui-input-block">
            ';
                $lay_verify = '';
                if ($column['COLUMN_TYPE'] === 'varchar(233)') {
                    if ($column['IS_NULLABLE'] === 'NO') {
                        $lay_verify = ' lay-verify="uploadimg"';
                    }
                    $columns .= '<button class="layui-btn layui-btn-sm upload-image" type="button">
                <i class="fa fa-image">
                </i>
                ' . $column['COLUMN_COMMENT'] . '
            </button>
            <input' . $lay_verify . ' name="' . $column['COLUMN_NAME'] . '" type="hidden" value="{$data[\'' . $column['COLUMN_NAME'] . '\']}"/>
            <div class="upload-image">
                <span>
                </span>
                <img class="upload-image" src="{$data[\'' . $column['COLUMN_NAME'] . '\']}"/>
            </div>';
                } else {
                    if ($column['IS_NULLABLE'] === 'NO') {
                        $lay_verify = ' lay-verify="required';
                        if (in_array($column['DATA_TYPE'], ['int', 'decimal', 'float', 'double'])) {
                            $lay_verify .= '|number';
                        }
                        $lay_verify .= '"';
                    }
                    $columns .= '<input autocomplete="off" class="layui-input"' . $lay_verify . ' name="' . $column['COLUMN_NAME'] . '" type="text" value="{$data[\'' . $column['COLUMN_NAME'] . '\']}"/>';
                }
                $columns .= '
        </div>
    </div>';
            }
        }
        $file = $this->module_path . 'view' . DS . $this->tn . DS . 'edit.html';
        if ($preview) {
            $file = str_replace(ROOT_PATH, '', $file);
        }
        $content = str_replace(['{{$columns}}'], [$columns], file_get_contents($this->template_path . 'view.edit.html.tpl'));
        return [$file, $content];
    }
    private function getTplIndexHtml($preview)
    {
        $file = $this->module_path . 'view' . DS . $this->tn . DS . 'index.html';
        if ($preview) {
            $file = str_replace(ROOT_PATH, '', $file);
        }
        $content = str_replace(['{{$tn_cn}}', '{{$tn}}', '{{$module}}'], [$this->tn_cn, $this->tn, $this->module], file_get_contents($this->template_path . 'view.index.html.tpl'));
        return [$file, $content];
    }
}
